// destructors
#include <iostream>
#include <string>
using namespace std;

class Demo1 {
    string ptr;
  public:
    // constructors:
    Demo1() : ptr() {cout<< "Demo1()"<<endl;}
    Demo1 (const string& str) : ptr((str)) {cout<< "Demo1(const string& str)" <<endl;}
    //Demo1(const string str): ptr(str) {cout << "Demo1(const string str)"<<endl;}
    Demo1 (string&& str) : ptr(str) {cout<< "Demo1(string&& str)" << endl;}
    // destructor:
    //Demo1 (Demo1 &o){ptr = o.ptr; cout << "Demo &o"<<endl;}
    Demo1 (Demo1 &o){ptr = o.ptr; *this = o;cout << "Demo &o"<<endl;}
    Demo1 (Demo1 &&o){ptr = o.ptr;cout << "Demo &&"<< endl;}
    Demo1 (const Demo1 &o){ptr = o.ptr;cout << "const Demo &o" << endl;}
    Demo1 (Demo1 *o){ptr = o->ptr;cout << "Demo1 *o"<<endl;}
    ~Demo1 () {}
    Demo1 &operator=(Demo1 &o){ptr = o.ptr;cout << "&oper=(&)" << endl;;}
    // access content:
    const string& content() const {return ptr;}
};

int constRef(const Demo1& a)
{

}

int noconstRef(Demo1 a)
{

}
int main () {
  string s1("1");
	cout<< s1 <<endl;
	cin>> s1 ;
  Demo1 bar (std::move(s1));
	cout<< s1 << "," << bar.content() <<endl;
	s1 = "2";

	cout<< s1 << "," << bar.content() <<endl;
  //Demo1 bar (static_cast<typename remove_reference<string>::type&&>(s1));
    cout << "bar1(s1)" << endl;
    Demo1 bar1 (s1);
    cout << "bar2(bar1)" << endl;
    Demo1 bar2 (bar1);
    cout << "bar3(&bar2)" << endl;
    Demo1 bar3(&bar2);
    cout << "Demo1 bar4 = bar1" << endl;
    Demo1 bar4 = bar1;
    cout << "bar4 = bar3" << endl;
    bar4 = bar3;
    //////////////////////
    cout << "function test." << endl;
    noconstRef(bar4);
    cout << "1" << endl;
    noconstRef(Demo1("123"));
}
